<?php
/**
 * Created by IntelliJ IDEA.
 * User: Administrator
 * Date: 2020/6/14
 * Time: 14:23
 */

namespace app\common\library\wechat;

use app\common\library\storage\Driver as StorageDriver;
use app\common\library\storage\engine\Qiniu;
use app\store\model\Setting as SettingModel;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use SplFileInfo;
use think\Exception;
use app\store\model\UploadFile;
use think\Log;

class WxCode
{
    private $config;
    private $fileName;
    private $file;

    public function __construct()
    {
        // 存储配置信息
        $this->config = SettingModel::getItem('storage');
    }

    public function makeNewQrCodeAction($bg, $avatarUrl, $Qr_code, $dest)
    {
        if ($bg) {
            $bg_file = file_get_contents($bg);
        } else {
            $bg_file = false;
        }

        $avatar_file = file_get_contents($avatarUrl);
        $logo = $this->changeAvatar($avatar_file);
        //小程序码与头像进行拼接
        return $this->makeOnePic($bg_file, $Qr_code, $logo, $dest);
    }


    private function makeOnePic($abg, $qr_code, $logo, $dest)  //二维码与头像组合
    {
        $qr_code = imagecreatefromstring($qr_code);  //生成的二维码底色为白色

        //设置二维码为透明底
        //imagesavealpha($qr_code, true);  //这个设置一定要加上
        $bg = imagecolorallocatealpha($qr_code, 255, 255, 255, 0);   //拾取一个完全透明的颜色,最后一个参数127为全透明
        imagefill($qr_code, 0, 0, $bg);

        $icon = imagecreatefromstring($logo);  //生成中间圆形logo （微信头像获取到的logo的大小为132px 132px）

        $qr_width = imagesx($qr_code);  //二维码图片宽度
        $qr_height = imagesy($qr_code);  //二维码图片高度
        $lg_width = imagesx($icon);  //logo图片宽度
        $lg_height = imagesy($icon);  //logo图片高度

//        var_dump($qr_width,$qr_height);
//        var_dump($lg_width,$lg_height);

        $qr_lg_width = $qr_width / 2.2;
        $scale = $lg_width / $qr_lg_width;
        $qr_lg_height = $lg_height / $scale;

        $start_width = ($qr_width - $lg_width) / 2;  //（获取logo的左上方的位置：( 外部的正方形-logo的宽 ) / 2,我这边存在1px的偏差 我就给+2啦）
//        var_dump($scale,$qr_lg_height);
//        var_dump($start_width);
        imagecopyresampled($qr_code, $icon, $start_width + 2, $start_width + 1, 0, 0, $qr_lg_width, $qr_lg_height, $lg_width, $lg_height);

        $this->fileName = $dest;
        //传回处理好的图片url
        if ($abg) {
            $abg = imagecreatefromstring($abg);
            $bg_width = imagesx($abg);//背景图宽度
	    $bg_height = imagesy($abg);//背景图高度
            imagecopyresampled($abg, $qr_code, $bg_width - 220, $bg_height - 220, 0, 0, 170, 170, $qr_width, $qr_height);
            imagepng($abg, WEB_PATH . $dest); //保存
        } else {
            imagepng($qr_code, WEB_PATH . $this->fileName); //保存
        }
        imagedestroy($abg);
        imagedestroy($qr_code);
        imagedestroy($icon);

        return $this->upload($dest);

    }

    private function upload($dest)
    {
        // 实例化存储驱动
        try {
            $engineName = $this->config['default'];
            $fileUrl = isset($this->config['engine'][$engineName]) ? $this->config['engine'][$engineName]['domain'] : '';
            if ($engineName == 'qiniu') {
                $this->file = new SplFileInfo(WEB_PATH . $dest);
                if ($this->qiniuUpload($this->file->getRealPath(), $this->config['engine'][$engineName])) {
                    // 存储域名

                    return $fileUrl . '/' . $this->fileName;
                }
            } else {
                return $fileUrl . '/' . $dest;
            }

        } catch (Exception $e) {
            Log::record("上传分享图片失败：" . $e->getMessage());
        }

    }

    private function qiniuUpload($realPath, $config)
    {
        // 构建鉴权对象
        $auth = new Auth($config['access_key'], $config['secret_key']);

        // 要上传的空间
        $token = $auth->uploadToken($config['bucket']);

        // 初始化 UploadManager 对象并进行文件的上传
        $uploadMgr = new UploadManager();

        // 调用 UploadManager 的 putFile 方法进行文件的上传
        list($result, $error) = $uploadMgr->putFile($token, $this->fileName, $realPath);

        if ($error !== null) {
            $this->error = $error->message();
            return false;
        }
        return true;

    }

    /**
     * 添加文件库上传记录
     * @param $group_id
     * @param $fileName
     * @param $fileInfo SplFileInfo An <b>SplFileInfo</b> object created for the file.
     * @param $fileType
     * @return UploadFile
     */
    private function addUploadFile($group_id, $fileName, $fileInfo, $fileType)
    {
        // 存储引擎
        $storage = $this->config['default'];
        // 存储域名
        $fileUrl = isset($this->config['engine'][$storage]) ? $this->config['engine'][$storage]['domain'] : '';
        // 添加文件库记录
        $model = new UploadFile;
        $model->add([
            'group_id' => $group_id > 0 ? (int)$group_id : 0,
            'storage' => $storage,
            'file_url' => $fileUrl,
            'file_name' => $fileName,
            'file_size' => $fileInfo->getSize(),
            'file_type' => $fileType,
            'extension' => pathinfo($fileInfo->getRealPath(), PATHINFO_EXTENSION),
        ]);
        return $model;
    }


    private function changeAvatar($avatar)
    {
        //处理用户头像为圆形icon
        $avatar = imagecreatefromstring($avatar);
        $w = imagesx($avatar);
        $h = imagesy($avatar);
        $w = min($w, $h);
        $h = $w;

        $img = imagecreatetruecolor($w, $h);
        imagesavealpha($img, true);
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
        imagefill($img, 0, 0, $bg);

        $r = $w / 2; //圆半径
        $y_x = $r; //圆心X坐标
        $y_y = $r; //圆心Y坐标
        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($avatar, $x, $y);

                if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                    imagesetpixel($img, $x, $y, $rgbColor);
                }
            }
        }

        ob_start();
        imagepng($img);
        imagedestroy($img);
        imagedestroy($avatar);
        $contents = ob_get_contents();
        ob_end_clean();  //清空缓存区

        return $contents;
    }
}
